//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension SimSpaceWeaver {
    // MARK: Enums

    public enum ClockStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case started = "STARTED"
        case starting = "STARTING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum ClockTargetStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case started = "STARTED"
        case stopped = "STOPPED"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum LifecycleManagementStrategy: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case byRequest = "ByRequest"
        case bySpatialSubdivision = "BySpatialSubdivision"
        case perWorker = "PerWorker"
        case unknown = "Unknown"
        public var description: String { return self.rawValue }
    }

    public enum SimulationAppStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case error = "ERROR"
        case started = "STARTED"
        case starting = "STARTING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum SimulationAppTargetStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case started = "STARTED"
        case stopped = "STOPPED"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum SimulationStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case deleted = "DELETED"
        case deleting = "DELETING"
        case failed = "FAILED"
        case snapshotInProgress = "SNAPSHOT_IN_PROGRESS"
        case started = "STARTED"
        case starting = "STARTING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum SimulationTargetStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case deleted = "DELETED"
        case started = "STARTED"
        case stopped = "STOPPED"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CloudWatchLogsLogGroup: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the Amazon CloudWatch Logs log group for the simulation. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference. For more information about log groups, see Working with log groups and log streams in the Amazon CloudWatch Logs User Guide.
        public let logGroupArn: String?

        @inlinable
        public init(logGroupArn: String? = nil) {
            self.logGroupArn = logGroupArn
        }

        private enum CodingKeys: String, CodingKey {
            case logGroupArn = "LogGroupArn"
        }
    }

    public struct CreateSnapshotInput: AWSEncodableShape {
        /// The Amazon S3 bucket and optional folder (object key prefix) where SimSpace Weaver creates the snapshot file. The Amazon S3 bucket must be in the same Amazon Web Services Region as the simulation.
        public let destination: S3Destination
        /// The name of the simulation.
        public let simulation: String

        @inlinable
        public init(destination: S3Destination, simulation: String) {
            self.destination = destination
            self.simulation = simulation
        }

        public func validate(name: String) throws {
            try self.destination.validate(name: "\(name).destination")
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case destination = "Destination"
            case simulation = "Simulation"
        }
    }

    public struct CreateSnapshotOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteAppInput: AWSEncodableShape {
        /// The name of the app.
        public let app: String
        /// The name of the domain of the app.
        public let domain: String
        /// The name of the simulation of the app.
        public let simulation: String

        @inlinable
        public init(app: String, domain: String, simulation: String) {
            self.app = app
            self.domain = domain
            self.simulation = simulation
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.app, key: "app")
            request.encodeQuery(self.domain, key: "domain")
            request.encodeQuery(self.simulation, key: "simulation")
        }

        public func validate(name: String) throws {
            try self.validate(self.app, name: "app", parent: name, max: 64)
            try self.validate(self.app, name: "app", parent: name, min: 1)
            try self.validate(self.app, name: "app", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.domain, name: "domain", parent: name, max: 64)
            try self.validate(self.domain, name: "domain", parent: name, min: 1)
            try self.validate(self.domain, name: "domain", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteAppOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteSimulationInput: AWSEncodableShape {
        /// The name of the simulation.
        public let simulation: String

        @inlinable
        public init(simulation: String) {
            self.simulation = simulation
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.simulation, key: "simulation")
        }

        public func validate(name: String) throws {
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteSimulationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DescribeAppInput: AWSEncodableShape {
        /// The name of the app.
        public let app: String
        /// The name of the domain of the app.
        public let domain: String
        /// The name of the simulation of the app.
        public let simulation: String

        @inlinable
        public init(app: String, domain: String, simulation: String) {
            self.app = app
            self.domain = domain
            self.simulation = simulation
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.app, key: "app")
            request.encodeQuery(self.domain, key: "domain")
            request.encodeQuery(self.simulation, key: "simulation")
        }

        public func validate(name: String) throws {
            try self.validate(self.app, name: "app", parent: name, max: 256)
            try self.validate(self.app, name: "app", parent: name, min: 1)
            try self.validate(self.app, name: "app", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.domain, name: "domain", parent: name, max: 64)
            try self.validate(self.domain, name: "domain", parent: name, min: 1)
            try self.validate(self.domain, name: "domain", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeAppOutput: AWSDecodableShape {
        /// The description of the app.
        public let description: String?
        /// The name of the domain of the app.
        public let domain: String?
        /// Information about the network endpoint for the custom app. You can use the endpoint to connect to the custom app.
        public let endpointInfo: SimulationAppEndpointInfo?
        public let launchOverrides: LaunchOverrides?
        /// The name of the app.
        public let name: String?
        /// The name of the simulation of the app.
        public let simulation: String?
        /// The current lifecycle state of the custom app.
        public let status: SimulationAppStatus?
        /// The desired lifecycle state of the custom app.
        public let targetStatus: SimulationAppTargetStatus?

        @inlinable
        public init(description: String? = nil, domain: String? = nil, endpointInfo: SimulationAppEndpointInfo? = nil, launchOverrides: LaunchOverrides? = nil, name: String? = nil, simulation: String? = nil, status: SimulationAppStatus? = nil, targetStatus: SimulationAppTargetStatus? = nil) {
            self.description = description
            self.domain = domain
            self.endpointInfo = endpointInfo
            self.launchOverrides = launchOverrides
            self.name = name
            self.simulation = simulation
            self.status = status
            self.targetStatus = targetStatus
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case domain = "Domain"
            case endpointInfo = "EndpointInfo"
            case launchOverrides = "LaunchOverrides"
            case name = "Name"
            case simulation = "Simulation"
            case status = "Status"
            case targetStatus = "TargetStatus"
        }
    }

    public struct DescribeSimulationInput: AWSEncodableShape {
        /// The name of the simulation.
        public let simulation: String

        @inlinable
        public init(simulation: String) {
            self.simulation = simulation
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.simulation, key: "simulation")
        }

        public func validate(name: String) throws {
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeSimulationOutput: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the simulation. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference.
        public let arn: String?
        /// The time when the simulation was created, expressed as the  number of seconds and milliseconds in UTC since the Unix epoch (0:0:0.000, January 1, 1970).
        public let creationTime: Date?
        /// The description of the simulation.
        public let description: String?
        /// A universally unique identifier (UUID) for this simulation.
        public let executionId: String?
        /// A collection of additional state information, such as
        /// domain and clock configuration.
        public let liveSimulationState: LiveSimulationState?
        /// Settings that control how SimSpace Weaver handles your simulation log data.
        public let loggingConfiguration: LoggingConfiguration?
        /// The maximum running time of the simulation, specified as a number of minutes (m or M), hours (h or H), or days (d or D). The simulation  stops when it reaches this limit. The maximum value is 14D, or its equivalent in the  other units. The default value is 14D. A value equivalent to 0 makes the simulation immediately transition to Stopping as soon as it reaches Started.
        public let maximumDuration: String?
        /// The name of the simulation.
        public let name: String?
        /// The Amazon Resource Name (ARN) of the Identity and Access Management (IAM) role that the simulation assumes to perform actions. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference. For more information about IAM roles, see IAM roles in the  Identity and Access Management User Guide.
        public let roleArn: String?
        /// An error message that SimSpace Weaver returns only if there is a problem with the simulation schema.
        public let schemaError: String?
        /// The location of the simulation schema in Amazon Simple Storage Service (Amazon S3). For more information about Amazon S3, see the  Amazon Simple Storage Service User Guide .
        public let schemaS3Location: S3Location?
        public let snapshotS3Location: S3Location?
        /// An error message that SimSpace Weaver returns only if a problem occurs when the simulation is in the STARTING state.
        public let startError: String?
        /// The current lifecycle state of the simulation.
        public let status: SimulationStatus?
        /// The desired lifecycle state of the simulation.
        public let targetStatus: SimulationTargetStatus?

        @inlinable
        public init(arn: String? = nil, creationTime: Date? = nil, description: String? = nil, executionId: String? = nil, liveSimulationState: LiveSimulationState? = nil, loggingConfiguration: LoggingConfiguration? = nil, maximumDuration: String? = nil, name: String? = nil, roleArn: String? = nil, schemaS3Location: S3Location? = nil, snapshotS3Location: S3Location? = nil, startError: String? = nil, status: SimulationStatus? = nil, targetStatus: SimulationTargetStatus? = nil) {
            self.arn = arn
            self.creationTime = creationTime
            self.description = description
            self.executionId = executionId
            self.liveSimulationState = liveSimulationState
            self.loggingConfiguration = loggingConfiguration
            self.maximumDuration = maximumDuration
            self.name = name
            self.roleArn = roleArn
            self.schemaError = nil
            self.schemaS3Location = schemaS3Location
            self.snapshotS3Location = snapshotS3Location
            self.startError = startError
            self.status = status
            self.targetStatus = targetStatus
        }

        @available(*, deprecated, message: "Members schemaError have been deprecated")
        @inlinable
        public init(arn: String? = nil, creationTime: Date? = nil, description: String? = nil, executionId: String? = nil, liveSimulationState: LiveSimulationState? = nil, loggingConfiguration: LoggingConfiguration? = nil, maximumDuration: String? = nil, name: String? = nil, roleArn: String? = nil, schemaError: String? = nil, schemaS3Location: S3Location? = nil, snapshotS3Location: S3Location? = nil, startError: String? = nil, status: SimulationStatus? = nil, targetStatus: SimulationTargetStatus? = nil) {
            self.arn = arn
            self.creationTime = creationTime
            self.description = description
            self.executionId = executionId
            self.liveSimulationState = liveSimulationState
            self.loggingConfiguration = loggingConfiguration
            self.maximumDuration = maximumDuration
            self.name = name
            self.roleArn = roleArn
            self.schemaError = schemaError
            self.schemaS3Location = schemaS3Location
            self.snapshotS3Location = snapshotS3Location
            self.startError = startError
            self.status = status
            self.targetStatus = targetStatus
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case creationTime = "CreationTime"
            case description = "Description"
            case executionId = "ExecutionId"
            case liveSimulationState = "LiveSimulationState"
            case loggingConfiguration = "LoggingConfiguration"
            case maximumDuration = "MaximumDuration"
            case name = "Name"
            case roleArn = "RoleArn"
            case schemaError = "SchemaError"
            case schemaS3Location = "SchemaS3Location"
            case snapshotS3Location = "SnapshotS3Location"
            case startError = "StartError"
            case status = "Status"
            case targetStatus = "TargetStatus"
        }
    }

    public struct Domain: AWSDecodableShape {
        /// The type of lifecycle management for apps in the domain. Indicates whether apps in this domain are managed (SimSpace Weaver starts and stops the apps) or unmanaged (you must start and stop the apps).  Lifecycle types     PerWorker – Managed: SimSpace Weaver starts one app on each worker.    BySpatialSubdivision – Managed: SimSpace Weaver starts one app for each spatial partition.    ByRequest – Unmanaged: You use the StartApp API to start the apps and use the StopApp API to stop the apps.
        public let lifecycle: LifecycleManagementStrategy?
        /// The name of the domain.
        public let name: String?

        @inlinable
        public init(lifecycle: LifecycleManagementStrategy? = nil, name: String? = nil) {
            self.lifecycle = lifecycle
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case lifecycle = "Lifecycle"
            case name = "Name"
        }
    }

    public struct LaunchOverrides: AWSEncodableShape & AWSDecodableShape {
        /// App launch commands and command line parameters that override the launch command configured in the simulation schema.
        public let launchCommands: [String]?

        @inlinable
        public init(launchCommands: [String]? = nil) {
            self.launchCommands = launchCommands
        }

        public func validate(name: String) throws {
            try self.launchCommands?.forEach {
                try validate($0, name: "launchCommands[]", parent: name, max: 1600)
                try validate($0, name: "launchCommands[]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case launchCommands = "LaunchCommands"
        }
    }

    public struct ListAppsInput: AWSEncodableShape {
        /// The name of the domain that you want to list apps for.
        public let domain: String?
        /// The maximum number of apps to list.
        public let maxResults: Int?
        /// If SimSpace Weaver returns nextToken, then there are more results available.  The value of nextToken is a unique pagination token for each page. To retrieve the next page,  call the operation again using the returned token. Keep all other arguments unchanged. If no results remain,  then nextToken is set to null. Each pagination token expires after 24 hours.  If you provide a token that isn't valid, then you receive an HTTP 400 ValidationException error.
        public let nextToken: String?
        /// The name of the simulation that you want to list apps for.
        public let simulation: String

        @inlinable
        public init(domain: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, simulation: String) {
            self.domain = domain
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.simulation = simulation
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.domain, key: "domain")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.simulation, key: "simulation")
        }

        public func validate(name: String) throws {
            try self.validate(self.domain, name: "domain", parent: name, max: 64)
            try self.validate(self.domain, name: "domain", parent: name, min: 1)
            try self.validate(self.domain, name: "domain", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListAppsOutput: AWSDecodableShape {
        /// The list of apps for the given simulation and domain.
        public let apps: [SimulationAppMetadata]?
        /// If SimSpace Weaver returns nextToken, then there are more results available.  The value of nextToken is a unique pagination token for each page. To retrieve the next page,  call the operation again using the returned token. Keep all other arguments unchanged. If no results remain,  then nextToken is set to null. Each pagination token expires after 24 hours.  If you provide a token that isn't valid, then you receive an HTTP 400 ValidationException error.
        public let nextToken: String?

        @inlinable
        public init(apps: [SimulationAppMetadata]? = nil, nextToken: String? = nil) {
            self.apps = apps
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case apps = "Apps"
            case nextToken = "NextToken"
        }
    }

    public struct ListSimulationsInput: AWSEncodableShape {
        /// The maximum number of simulations to list.
        public let maxResults: Int?
        /// If SimSpace Weaver returns nextToken, then there are more results available.  The value of nextToken is a unique pagination token for each page. To retrieve the next page,  call the operation again using the returned token. Keep all other arguments unchanged. If no results remain,  then nextToken is set to null. Each pagination token expires after 24 hours.  If you provide a token that isn't valid, then you receive an HTTP 400 ValidationException error.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSimulationsOutput: AWSDecodableShape {
        /// If SimSpace Weaver returns nextToken, then there are more results available.  The value of nextToken is a unique pagination token for each page. To retrieve the next page,  call the operation again using the returned token. Keep all other arguments unchanged. If no results remain,  then nextToken is set to null. Each pagination token expires after 24 hours.  If you provide a token that isn't valid, then you receive an HTTP 400 ValidationException error.
        public let nextToken: String?
        /// The list of simulations.
        public let simulations: [SimulationMetadata]?

        @inlinable
        public init(nextToken: String? = nil, simulations: [SimulationMetadata]? = nil) {
            self.nextToken = nextToken
            self.simulations = simulations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case simulations = "Simulations"
        }
    }

    public struct ListTagsForResourceInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "ResourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1600)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(?:aws|aws-cn|aws-us-gov):simspaceweaver:([a-z]{2}-[a-z]+-\\d{1}):(\\d{12})?:([a-z]+)\\/(.+)$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceOutput: AWSDecodableShape {
        /// The list of tags for the resource.
        public let tags: [String: String]?

        @inlinable
        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct LiveSimulationState: AWSDecodableShape {
        /// A list of simulation clocks.  At this time, a simulation has only one clock.
        public let clocks: [SimulationClock]?
        /// A list of domains for the simulation. For more information about domains, see Key concepts: Domains in the SimSpace Weaver User Guide.
        public let domains: [Domain]?

        @inlinable
        public init(clocks: [SimulationClock]? = nil, domains: [Domain]? = nil) {
            self.clocks = clocks
            self.domains = domains
        }

        private enum CodingKeys: String, CodingKey {
            case clocks = "Clocks"
            case domains = "Domains"
        }
    }

    public struct LogDestination: AWSDecodableShape {
        /// An Amazon CloudWatch Logs log group that stores simulation log data. For more information about log groups, see Working with log groups and log streams in the Amazon CloudWatch Logs User Guide.
        public let cloudWatchLogsLogGroup: CloudWatchLogsLogGroup?

        @inlinable
        public init(cloudWatchLogsLogGroup: CloudWatchLogsLogGroup? = nil) {
            self.cloudWatchLogsLogGroup = cloudWatchLogsLogGroup
        }

        private enum CodingKeys: String, CodingKey {
            case cloudWatchLogsLogGroup = "CloudWatchLogsLogGroup"
        }
    }

    public struct LoggingConfiguration: AWSDecodableShape {
        /// A list of the locations where SimSpace Weaver sends simulation log data.
        public let destinations: [LogDestination]?

        @inlinable
        public init(destinations: [LogDestination]? = nil) {
            self.destinations = destinations
        }

        private enum CodingKeys: String, CodingKey {
            case destinations = "Destinations"
        }
    }

    public struct S3Destination: AWSEncodableShape {
        /// The name of an Amazon S3 bucket. For more information about buckets, see Creating, configuring, and working with Amazon S3 buckets in the Amazon Simple Storage Service User Guide.
        public let bucketName: String
        /// A string prefix for an Amazon S3 object key. It's usually a folder name. For more information about folders in Amazon S3, see Organizing objects in the Amazon S3 console using folders in the Amazon Simple Storage Service User Guide.
        public let objectKeyPrefix: String?

        @inlinable
        public init(bucketName: String, objectKeyPrefix: String? = nil) {
            self.bucketName = bucketName
            self.objectKeyPrefix = objectKeyPrefix
        }

        public func validate(name: String) throws {
            try self.validate(self.bucketName, name: "bucketName", parent: name, max: 63)
            try self.validate(self.bucketName, name: "bucketName", parent: name, min: 3)
            try self.validate(self.objectKeyPrefix, name: "objectKeyPrefix", parent: name, max: 1024)
        }

        private enum CodingKeys: String, CodingKey {
            case bucketName = "BucketName"
            case objectKeyPrefix = "ObjectKeyPrefix"
        }
    }

    public struct S3Location: AWSEncodableShape & AWSDecodableShape {
        /// The name of an Amazon S3 bucket. For more information about buckets, see Creating, configuring, and working with Amazon S3 buckets in the Amazon Simple Storage Service User Guide.
        public let bucketName: String
        /// The key name of an object in Amazon S3. For more information about Amazon S3 objects and object keys, see Uploading, downloading, and working with objects in Amazon S3 in the Amazon Simple Storage Service User Guide.
        public let objectKey: String

        @inlinable
        public init(bucketName: String, objectKey: String) {
            self.bucketName = bucketName
            self.objectKey = objectKey
        }

        public func validate(name: String) throws {
            try self.validate(self.bucketName, name: "bucketName", parent: name, max: 63)
            try self.validate(self.bucketName, name: "bucketName", parent: name, min: 3)
            try self.validate(self.objectKey, name: "objectKey", parent: name, max: 1024)
            try self.validate(self.objectKey, name: "objectKey", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case bucketName = "BucketName"
            case objectKey = "ObjectKey"
        }
    }

    public struct SimulationAppEndpointInfo: AWSDecodableShape {
        /// The IP address of the app. SimSpace Weaver dynamically assigns this IP address when the app starts.
        public let address: String?
        /// The inbound TCP/UDP port numbers of the app. The combination of an IP address and a port number form a network endpoint.
        public let ingressPortMappings: [SimulationAppPortMapping]?

        @inlinable
        public init(address: String? = nil, ingressPortMappings: [SimulationAppPortMapping]? = nil) {
            self.address = address
            self.ingressPortMappings = ingressPortMappings
        }

        private enum CodingKeys: String, CodingKey {
            case address = "Address"
            case ingressPortMappings = "IngressPortMappings"
        }
    }

    public struct SimulationAppMetadata: AWSDecodableShape {
        /// The domain of the app. For more information about domains, see Key concepts: Domains in the SimSpace Weaver User Guide.
        public let domain: String?
        /// The name of the app.
        public let name: String?
        /// The name of the simulation of the app.
        public let simulation: String?
        /// The current status of the app.
        public let status: SimulationAppStatus?
        /// The desired status of the app.
        public let targetStatus: SimulationAppTargetStatus?

        @inlinable
        public init(domain: String? = nil, name: String? = nil, simulation: String? = nil, status: SimulationAppStatus? = nil, targetStatus: SimulationAppTargetStatus? = nil) {
            self.domain = domain
            self.name = name
            self.simulation = simulation
            self.status = status
            self.targetStatus = targetStatus
        }

        private enum CodingKeys: String, CodingKey {
            case domain = "Domain"
            case name = "Name"
            case simulation = "Simulation"
            case status = "Status"
            case targetStatus = "TargetStatus"
        }
    }

    public struct SimulationAppPortMapping: AWSDecodableShape {
        /// The TCP/UDP port number of the running app. SimSpace Weaver dynamically assigns this port number when the app starts. SimSpace Weaver maps the Declared port to the Actual port. Clients connect to the app using the app's IP address and the Actual port number.
        public let actual: Int?
        /// The TCP/UDP port number of the app, declared in the simulation schema. SimSpace Weaver maps the Declared port to the Actual port. The source code for the app should bind to the Declared port.
        public let declared: Int?

        @inlinable
        public init(actual: Int? = nil, declared: Int? = nil) {
            self.actual = actual
            self.declared = declared
        }

        private enum CodingKeys: String, CodingKey {
            case actual = "Actual"
            case declared = "Declared"
        }
    }

    public struct SimulationClock: AWSDecodableShape {
        /// The current status of the simulation clock.
        public let status: ClockStatus?
        /// The desired status of the simulation clock.
        public let targetStatus: ClockTargetStatus?

        @inlinable
        public init(status: ClockStatus? = nil, targetStatus: ClockTargetStatus? = nil) {
            self.status = status
            self.targetStatus = targetStatus
        }

        private enum CodingKeys: String, CodingKey {
            case status = "Status"
            case targetStatus = "TargetStatus"
        }
    }

    public struct SimulationMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the simulation. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference.
        public let arn: String?
        /// The time when the simulation was created, expressed as the  number of seconds and milliseconds in UTC since the Unix epoch (0:0:0.000, January 1, 1970).
        public let creationTime: Date?
        /// The name of the simulation.
        public let name: String?
        /// The current status of the simulation.
        public let status: SimulationStatus?
        /// The desired status of the simulation.
        public let targetStatus: SimulationTargetStatus?

        @inlinable
        public init(arn: String? = nil, creationTime: Date? = nil, name: String? = nil, status: SimulationStatus? = nil, targetStatus: SimulationTargetStatus? = nil) {
            self.arn = arn
            self.creationTime = creationTime
            self.name = name
            self.status = status
            self.targetStatus = targetStatus
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case creationTime = "CreationTime"
            case name = "Name"
            case status = "Status"
            case targetStatus = "TargetStatus"
        }
    }

    public struct StartAppInput: AWSEncodableShape {
        /// A value that you provide to ensure that repeated calls to this API operation using the same parameters complete only once. A ClientToken is also known as an idempotency token. A ClientToken expires after 24 hours.
        public let clientToken: String?
        /// The description of the app.
        public let description: String?
        /// The name of the domain of the app.
        public let domain: String
        public let launchOverrides: LaunchOverrides?
        /// The name of the app.
        public let name: String
        /// The name of the simulation of the app.
        public let simulation: String

        @inlinable
        public init(clientToken: String? = StartAppInput.idempotencyToken(), description: String? = nil, domain: String, launchOverrides: LaunchOverrides? = nil, name: String, simulation: String) {
            self.clientToken = clientToken
            self.description = description
            self.domain = domain
            self.launchOverrides = launchOverrides
            self.name = name
            self.simulation = simulation
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 32)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.description, name: "description", parent: name, max: 500)
            try self.validate(self.domain, name: "domain", parent: name, max: 64)
            try self.validate(self.domain, name: "domain", parent: name, min: 1)
            try self.validate(self.domain, name: "domain", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.launchOverrides?.validate(name: "\(name).launchOverrides")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case description = "Description"
            case domain = "Domain"
            case launchOverrides = "LaunchOverrides"
            case name = "Name"
            case simulation = "Simulation"
        }
    }

    public struct StartAppOutput: AWSDecodableShape {
        /// The name of the domain of the app.
        public let domain: String?
        /// The name of the app.
        public let name: String?
        /// The name of the simulation of the app.
        public let simulation: String?

        @inlinable
        public init(domain: String? = nil, name: String? = nil, simulation: String? = nil) {
            self.domain = domain
            self.name = name
            self.simulation = simulation
        }

        private enum CodingKeys: String, CodingKey {
            case domain = "Domain"
            case name = "Name"
            case simulation = "Simulation"
        }
    }

    public struct StartClockInput: AWSEncodableShape {
        /// The name of the simulation.
        public let simulation: String

        @inlinable
        public init(simulation: String) {
            self.simulation = simulation
        }

        public func validate(name: String) throws {
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case simulation = "Simulation"
        }
    }

    public struct StartClockOutput: AWSDecodableShape {
        public init() {}
    }

    public struct StartSimulationInput: AWSEncodableShape {
        /// A value that you provide to ensure that repeated calls to this API operation using the same parameters complete only once. A ClientToken is also known as an idempotency token. A ClientToken expires after 24 hours.
        public let clientToken: String?
        /// The description of the simulation.
        public let description: String?
        /// The maximum running time of the simulation, specified as a number of minutes (m or M), hours (h or H), or days (d or D). The simulation  stops when it reaches this limit. The maximum value is 14D, or its equivalent in the  other units. The default value is 14D. A value equivalent to 0 makes the simulation immediately transition to Stopping as soon as it reaches Started.
        public let maximumDuration: String?
        /// The name of the simulation.
        public let name: String
        /// The Amazon Resource Name (ARN) of the Identity and Access Management (IAM) role that the simulation assumes to perform actions. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference. For more information about IAM roles, see IAM roles in the  Identity and Access Management User Guide.
        public let roleArn: String
        /// The location of the simulation schema in Amazon Simple Storage Service (Amazon S3). For more information about Amazon S3, see the  Amazon Simple Storage Service User Guide . Provide a SchemaS3Location to start your simulation from a schema. If you provide a SchemaS3Location then you can't provide a SnapshotS3Location.
        public let schemaS3Location: S3Location?
        /// The location of the snapshot .zip file in Amazon Simple Storage Service (Amazon S3). For more information about Amazon S3, see the  Amazon Simple Storage Service User Guide . Provide a SnapshotS3Location to start your simulation from a snapshot. The Amazon S3 bucket must be in the same Amazon Web Services Region as the simulation. If you provide a SnapshotS3Location then you can't provide a SchemaS3Location.
        public let snapshotS3Location: S3Location?
        /// A list of tags for the simulation. For more information about tags, see Tagging Amazon Web Services resources in the Amazon Web Services General Reference.
        public let tags: [String: String]?

        @inlinable
        public init(clientToken: String? = StartSimulationInput.idempotencyToken(), description: String? = nil, maximumDuration: String? = nil, name: String, roleArn: String, schemaS3Location: S3Location? = nil, snapshotS3Location: S3Location? = nil, tags: [String: String]? = nil) {
            self.clientToken = clientToken
            self.description = description
            self.maximumDuration = maximumDuration
            self.name = name
            self.roleArn = roleArn
            self.schemaS3Location = schemaS3Location
            self.snapshotS3Location = snapshotS3Location
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 32)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.description, name: "description", parent: name, max: 500)
            try self.validate(self.maximumDuration, name: "maximumDuration", parent: name, max: 6)
            try self.validate(self.maximumDuration, name: "maximumDuration", parent: name, min: 2)
            try self.validate(self.maximumDuration, name: "maximumDuration", parent: name, pattern: "^\\d{1,5}[mhdMHD]$")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.roleArn, name: "roleArn", parent: name, max: 1600)
            try self.validate(self.roleArn, name: "roleArn", parent: name, pattern: "^arn:(?:aws|aws-cn|aws-us-gov):iam::(\\d{12})?:role\\/(.+)$")
            try self.schemaS3Location?.validate(name: "\(name).schemaS3Location")
            try self.snapshotS3Location?.validate(name: "\(name).snapshotS3Location")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case description = "Description"
            case maximumDuration = "MaximumDuration"
            case name = "Name"
            case roleArn = "RoleArn"
            case schemaS3Location = "SchemaS3Location"
            case snapshotS3Location = "SnapshotS3Location"
            case tags = "Tags"
        }
    }

    public struct StartSimulationOutput: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the simulation. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference.
        public let arn: String?
        /// The time when the simulation was created, expressed as the  number of seconds and milliseconds in UTC since the Unix epoch (0:0:0.000, January 1, 1970).
        public let creationTime: Date?
        /// A universally unique identifier (UUID) for this simulation.
        public let executionId: String?

        @inlinable
        public init(arn: String? = nil, creationTime: Date? = nil, executionId: String? = nil) {
            self.arn = arn
            self.creationTime = creationTime
            self.executionId = executionId
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case creationTime = "CreationTime"
            case executionId = "ExecutionId"
        }
    }

    public struct StopAppInput: AWSEncodableShape {
        /// The name of the app.
        public let app: String
        /// The name of the domain of the app.
        public let domain: String
        /// The name of the simulation of the app.
        public let simulation: String

        @inlinable
        public init(app: String, domain: String, simulation: String) {
            self.app = app
            self.domain = domain
            self.simulation = simulation
        }

        public func validate(name: String) throws {
            try self.validate(self.app, name: "app", parent: name, max: 64)
            try self.validate(self.app, name: "app", parent: name, min: 1)
            try self.validate(self.app, name: "app", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.domain, name: "domain", parent: name, max: 64)
            try self.validate(self.domain, name: "domain", parent: name, min: 1)
            try self.validate(self.domain, name: "domain", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case app = "App"
            case domain = "Domain"
            case simulation = "Simulation"
        }
    }

    public struct StopAppOutput: AWSDecodableShape {
        public init() {}
    }

    public struct StopClockInput: AWSEncodableShape {
        /// The name of the simulation.
        public let simulation: String

        @inlinable
        public init(simulation: String) {
            self.simulation = simulation
        }

        public func validate(name: String) throws {
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case simulation = "Simulation"
        }
    }

    public struct StopClockOutput: AWSDecodableShape {
        public init() {}
    }

    public struct StopSimulationInput: AWSEncodableShape {
        /// The name of the simulation.
        public let simulation: String

        @inlinable
        public init(simulation: String) {
            self.simulation = simulation
        }

        public func validate(name: String) throws {
            try self.validate(self.simulation, name: "simulation", parent: name, max: 64)
            try self.validate(self.simulation, name: "simulation", parent: name, min: 1)
            try self.validate(self.simulation, name: "simulation", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case simulation = "Simulation"
        }
    }

    public struct StopSimulationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct TagResourceInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource that you want to add tags to. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference.
        public let resourceArn: String
        /// A list of tags to apply to the resource.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "ResourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1600)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(?:aws|aws-cn|aws-us-gov):simspaceweaver:([a-z]{2}-[a-z]+-\\d{1}):(\\d{12})?:([a-z]+)\\/(.+)$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct TagResourceOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceInput: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource that you want to remove tags from. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference.
        public let resourceArn: String
        /// A list of tag keys to remove from the resource.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "ResourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1600)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(?:aws|aws-cn|aws-us-gov):simspaceweaver:([a-z]{2}-[a-z]+-\\d{1}):(\\d{12})?:([a-z]+)\\/(.+)$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceOutput: AWSDecodableShape {
        public init() {}
    }
}

// MARK: - Errors

/// Error enum for SimSpaceWeaver
public struct SimSpaceWeaverErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case tooManyTagsException = "TooManyTagsException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize SimSpaceWeaver
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    public static var conflictException: Self { .init(.conflictException) }
    public static var internalServerException: Self { .init(.internalServerException) }
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    public static var tooManyTagsException: Self { .init(.tooManyTagsException) }
    public static var validationException: Self { .init(.validationException) }
}

extension SimSpaceWeaverErrorType: Equatable {
    public static func == (lhs: SimSpaceWeaverErrorType, rhs: SimSpaceWeaverErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension SimSpaceWeaverErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
